package com.acme.bankapp.service.email;

import com.acme.bankapp.domain.bank.Client;
import com.acme.bankapp.domain.email.Email;
import com.acme.bankapp.domain.email.Queue;
import com.acme.bankapp.domain.email.impl.EmailImpl;
import com.acme.bankapp.domain.email.impl.QueueImpl;

public class EmailService implements Runnable {

	static final String TO = "to@db.com";
	static final String FROM = "from@db.com";
	static final String SUBJECT = "Client is added";
	static final String MESSAGE = "Client is added. Our congratulations!";
	
	private Queue queue = new QueueImpl();
	private Thread processThread;

	private static volatile EmailService instance;
	
	private EmailService() {
		processThread = new Thread(this);
		processThread.start();
	}
	
	public static EmailService getEmailService() {
		// thread-safe singleton - double checked locking
		if (instance == null) {
			synchronized (EmailService.class) {
				if (instance == null)
					instance = new EmailService();
			}
		}
		
		return instance;
	}
	
	private Email createEmail(Client client) {
		Email email = new EmailImpl(FROM, TO, SUBJECT, MESSAGE, client);
		
		return email;
	}
	
	public void sendNotificationEmail(Client client) {	
		queue.addEmail(createEmail(client));
	}
	
	public void close() {
		queue.close();
	}

	@Override
	public void run() {
		// check mails until closing this service and queue is empty
		while (!(queue.isClosing() && queue.isEmpty())) {
			try {
				Email email = queue.getEmail();
			
				if (email != null)
					System.out.println(email);
				// just to test slow message processing
				Thread.sleep(1000);
			} catch (InterruptedException e) { }
		}
		System.out.println("email service has finished its work");
	}	
}
